package com.tests;

import be.ac.ulg.montefiore.run.jahmm.Hmm;
import be.ac.ulg.montefiore.run.jahmm.Opdf;
import be.ac.ulg.montefiore.run.jahmm.OpdfGaussian;
import be.ac.ulg.montefiore.run.jahmm.apps.cli.*;
import be.ac.ulg.montefiore.run.jahmm.io.FileFormatException;
import be.ac.ulg.montefiore.run.jahmm.io.HmmReader;
import be.ac.ulg.montefiore.run.jahmm.io.OpdfReader;
import com.qp.MainCaller;
import com.qp.OutputDistributionCalculator;
import com.utils.Constants;
import com.utils.HmmUtils;
import junit.framework.TestCase;
import org.junit.Test;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;


/**
 * Created with IntelliJ IDEA.
 * User: bigmar
 * Date: 12/18/14
 * Time: 9:37 AM
 * To change this template use File | Settings | File Templates.
 */
public class TestMain
{
    private static String mainDir="tests\\";

    @Test
    public void testTrivial2States() throws Exception
    {
        String fileName="trivial2states";

        call(fileName);

    }


    @Test
    public void testTrivial3States() throws Exception
    {
        String fileName="trivial3states";
        call(fileName);
    }

    @Test
    public void testTrivial4States() throws Exception
    {
        String fileName="trivial4states";
        call(fileName);
    }
    @Test
    public void testPaper() throws Exception
    {
        String fileName="paper";
        call(fileName);
    }

//
//    @Test
//    public void testTrivial10States() throws Exception
//    {
//        String fileName="trivial10states";
//        call(fileName);
//    }


    @Test
    public void testEqual2States() throws Exception
    {
        String fileName="equal2states";
        call(fileName);

    }


    @Test
    public void testEqual3States() throws Exception
    {
        String fileName="equal3states";
        call(fileName);

    }

    @Test
    public void testEqual4States() throws Exception
    {
        String fileName="equal4states";
        call(fileName);

    }
//
//    @Test
//    public void testEqual10States() throws Exception
//    {
//        String fileName="equal10states";
//        call(fileName);
//
//    }

    @Test
    public void testChange2States() throws Exception
    {
        String fileName="change2States";
        call(fileName);

    }
    @Test
    public void testChange3States() throws Exception
    {
        String fileName="change3States";
        call(fileName);

    }
    @Test
    public void testChange4States() throws Exception
    {
        String fileName="change4States";
        call(fileName);

    }
//    @Test
//    public void testChange10States() throws Exception
//    {
//        String fileName="change10States";
//        call(fileName);
//
//    }

    @Test
    public void testGenericDistribution2States() throws Exception
    {
        String fileName="genericDistribution2States";
        call(fileName);

    }

    @Test
    public void testGenericDistribution3States() throws Exception
    {
        String fileName="genericDistribution3States";
        call(fileName);

    }

    @Test
    public void testGenericDistribution4States() throws Exception
    {
        String fileName="genericDistribution4States";
        call(fileName);

    }

//    @Test
//    public void test4TrivialModels() throws Exception {
//        new MainCaller().call("C:\\workspace\\jahmm-0.6.1\\trivial.seq", 4);
//    }
    public void call(String fileName) throws Exception
    {
        String sequenceFileName=mainDir+fileName+".seq";
        String hmmFileName=mainDir+fileName+".hmm";


        Hmm hmm= HmmUtils.readHmm(hmmFileName);
        Cli.run("generate", "-opdf", "gaussian", "-i", hmmFileName, "-os", sequenceFileName);

        // calculate expected eta
        double[] expectedEtaEstimation=ExpectedEtaCalculator.calculateExpectedEta(hmm);


        MainCaller mainCaller=new MainCaller();
        Hmm newHmm=mainCaller.call(sequenceFileName, hmm.nbStates());
        double[] etaEstimation=mainCaller.getEtaEstimation();

        HmmUtils.printHmm(newHmm);
        HmmUtils.orderHmm(newHmm);


        double retVal=compareEtas(etaEstimation, expectedEtaEstimation);
        System.out.println("eta comparison resulted with  difference of "+(retVal*100)+"%");
        HmmUtils.compareHmms(hmm, newHmm);
//        if (retVal> Constants.allowDifRatio||retVal<0)
//            TestCase.assertTrue("etaComparison failed, difference is " + (retVal * 100) + "%", false);
    }
    private double compareEtas(double[] etaEstimation, double[] expectedEtaEstimation)
    {
        double maxDif=0;
        double max=0;

        int length=expectedEtaEstimation.length;
        for (int i=0; i<length; ++i)
        {
            double dif=Math.abs(etaEstimation[i]-expectedEtaEstimation[i]);

            if (dif>maxDif)
                maxDif=dif;
            if (Math.abs(etaEstimation[i])>max)
                max=Math.abs(etaEstimation[i]);
            if (Math.abs(expectedEtaEstimation[i])>max)
                max=Math.abs(expectedEtaEstimation[i]);
        }
        return maxDif/max;
    }


}
